.TH LS_NAME_VALUE "8" "July 2023" "lsscsi\-0.33" LSSCSI
.SH NAME
ls_name_value \- for browsing names and corresponding values in sysfs
.SH SYNOPSIS
.B ls_name_value
[\fI\-\-all\fR] [\fI\-\-dir\fR] [\fI\-\-empty\fR] [\fI\-\-help\fR]
[\fI\-\-nosym\fR] [\fI\-\-num=NUM\fR] [\fI\-\-otherfs\fR] [\fI\-\-show\fR]
[\fI\-\-verbose\fR] [\fI\-\-version\fR] [\fI\-\-write\fR] [\fINAME\fR ...]
.SH DESCRIPTION
.\" Add any additional description here
This bash shell script is designed to give an overview of the (file)names
and their corresponding values in the sysfs pseudo file system found in
Linux. Only printable ASCII is shown for each value, on the same line
following the (file)name and a colon. That will be referred to as
a "name:value pair" in the following.
.PP
If no \fINAME\fR is given then all regular files in the current directory
have their name:value pair displayed. Hidden regular files (i.e. those
starting with ".") are not shown. If one or more \fINAME\fRs are given
then their corresponding name:value pairs are displayed. An exception is if
only one \fINAME\fR is given and that is a directory (or a symlink to a
directory) then that directory is entered and all regular files in that
directory have their name:value pair displayed.
.PP
A simple example follows where "power_role" is a regular file:
    $ ls_name_value /sys/class/typec/port1/power_role
    power_role : source [sink]
.PP
The emphasis of this script is to get an overview of multiple name:value
pairs in the same or nearby directories. This is done at the expense
of accurate renderings of the associated values. Other tools may be used
to get better renderings of particular values, for example the
.B od
and
.B hd (hexdump)
Unix commands if the value contains binary data.
.PP
This script may also be suitable for other pseudo file systems, but not
if they pause a Unix read(2) waiting for an event to occur. The tracefs
pseudo file system has waiting read(2)s and this is an issue since an
instance of tracefs is often mounted under sysfs (e.g. /sys/kernel/trace ).
Due to this issue, every time this script tries to descend into a
directory, it checks if it is still in the original file system instance.
If not, it does not descend and outputs a "<different filesystem>" message.
An example that shows this action is:
    $ ls_name_value \-d /dev /sys
    >> descend to: /dev/:
        acpi_thermal_rel : <char device>
        ....
    >> not descending to: /sys/: <different filesystem>
.br
This occurs because /dev is contained in an instance of the devfs file
system  while /sys is contained in an instance of sysfs.
.PP
The name shown in each "name:value pair" is its basename if \fINAME\fR is
given with an absolute or relative path. The value shown will only contain
printable ASCII characters, truncated to 256 bytes. If any character (byte)
read from a regular filename has its top bit set then the whole value is
replaced with "<contains non\-ASCII chars>". If the name has write
permissions set for the accessing user and no read permissions set then the
whole value is replaced by "<write_only>". If the value in the
name cannot be read (and the name is a regular file) then the whole value
is replaced by "<cannot access>".
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
.TP
\fB\-a\fR, \fB\-\-all\fR
following Unix practice, by default when filenames in a directory are listed,
those starting with '.' are hidden (i.e. not listed). When this option
is given, filenames starting with '.' are included. The pseudo
filenames '.' and '..' are excluded making the filenames shown similar to
the output of 'ls \-A'.
.TP
\fB\-d\fR, \fB\-\-dir\fR
When give once, if any files in the \fINAME\fR list are directories, then
this script enters each directory and lists its name:value pairs. Those
name:value pairs are preceded by four spaces to show 1 level of nesting.
If the \fINAME\fR list is empty, then the contents of the current
working directory are used as a name list.
.br
If this option is given twice, then up to two levels directories are
entered. The name:value pairs at the second level are preceded by eight
spaces.
.br
The is a special case when a single element \fINAME\fR list is given and
that name is a directory. This script will enter that directory and list
its name:value pairs without the need for this option.
.TP
\fB\-e\fR, \fB\-\-empty\fR
any many cases the value associated a filename is empty. By default, nothing
will appear to the right of then colon separating  the name and value. When
this option is given, if the value is empty, the string '<empty>' is output.
.TP
\fB\-h\fR, \fB\-\-help\fR
print out the usage message then exit.
.TP
\fB\-N\fR, \fB\-\-nosym\fR
in sysfs most symbolic links (symlinks) point to other directories rather
than regular files. Sometimes following symlinks and expanding the directory
adds too much noise so this option prunes out symlinks to directories.
.TP
\fB\-n\fR, \fB\-\-num\fR=\fINUM\fR
\fINUM\fR is the maximum number of bytes in the values shown. \fINUM\fR is
required to be greater than zero. 256 bytes is the default for \fINUM\fR.
.br
This option does not apply to the destination path shown for symbolic
links or the directory name when descending into that directory.
.TP
\fB\-o\fR, \fB\-\-otherfs\fR
as explained in the DESCRIPTION section above, sometimes descending into
directories in other file systems can cause issues. So the default action
is to prune any branch (directory) that is not in the same file system as
the first file (which may be a directory) processed. Giving this option skips
the file system check.
.TP
\fB\-s\fR, \fB\-\-show\fR
usually only regular files are shown in name:value pair format. The main
exception is a directory which this utility will "descend" into. For
example it is shown like this:
    $ ls_name_value \-d /sys/class/typec/port1
    data_role : [host] device
    >> descend to: device/:
        driver_override : (null)
        modalias : acpi:USBC000:PNP0CA0:
        ....
.br
Directories that are not visited are not shown by default. Also other file
types, sometimes called "specials" are not shown. Those specials include
char and block devices, pipes and sockets.
.br
When this option is given all file types are shown. For directories that
are not descended into there are two cases:
    \fBalso a symlink\fR : the value is "\-\-\-> <link_destination>"
    \fBnot a symlink\fR : the value is "\-\->"
.br
For other special file types the value is the file type between angle
brackets (e.g. "<block device>" ).
.TP
\fB\-v\fR, \fB\-\-verbose\fR
increase level or verbosity.
.TP
\fB\-V\fR, \fB\-\-version\fR
prints out the version string then exits.
.TP
\fB\-w\fR, \fB\-\-write\fR
the separator between the <name> and <value> is normally ":". If this option
is given and the filename <name> has both read and write permissions for
the current user then the separator is changed to "+".
.SH EXAMPLES
There is no command line option to exclude directories which would be useful
when using the \fI\-\-dir\fR option. A case where this might be helpful is
in procfs (e.g. /proc ) as descending into each running process (thread) may
create a lot of noise and perhaps a loop as the ls_name_value script itself
is creating (and removing) lots of processes (threads) as it scans. Processes
in that directory will match a grep regex like "^[0\-9]" which means starting
with a digit.
    $ cd /proc
    $ ls_name_value \-n 32 \-d  $( ls \-A | grep \-v "^[0\-9]" )
.br
The '\-v' option on grep inverts a selection (e.g. "give me the lines that
do not match ..."). The above invocation shows up to 32 bytes of the contents
of regular files in /proc and descends into all directories that do
.B not
start with a digit (i.e. information about every running process). For the
directories that it does descend into, it will show up to 32 bytes of the
contents of regular files it finds, indented by four spaces. There still
is a directory called "thread\-self" that is a symbolic link to a process
directory that is scanned. The \fI\-\-nosym\fR option would prune
the "thread\-self" along with any other symlinks (and there are several).
In some senses symlinks are evil.
.PP
To list the contents of all files called 'connect_type' in sysfs, the
following could be done:
    $ find /sys \-name connect_type \-print0 | xargs \-0 ls_name_value
.br
The output will be one line per match. The 'cat' utility could be used but
ls_name_value guards against long files and files containing binary that
could trash the console output. If there are a lot of matching files then
the maximum size of a command line may become an issue. If so:
   $ find /sys \-name connect_type \-exec ls_name_value {} \\;
.br
should do the trick. If the filename contained spaces then the second version
would have problems. It doesn't in the case of 'connect_type' but sysfs does
contain a few filenames with spaces: "/sys/bus/pnp/drivers/i8042 aux" .
.SH NOTES
This utility's functionality overlaps somewhat with the systool utility.
systool knows the high level structure of sysfs and offers a better overview.
However if information is deeply nested (e.g. /sys/class/typec/ for USB PD)
then this utility gives better "drilling down" facilities. For example the
USB PD source capabilities of an AC adapter powering a laptop may be found
at /sys/class/typec/port1\-partner/usb_power_delivery/source\-capabilities/*
which can be better viewed with this utility.
.SH AUTHORS
Written by D. Gilbert
.SH COPYRIGHT
Copyright \(co 2023 Douglas Gilbert
.br
This software is distributed under a BSD\-2\-Clause license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.SH "SEE ALSO"
.B lsscsi(this package), od(GNU coreutils), hd(util\-linux), getopt(1)
.B systool(sysfsutils), udevadm(systemd)
